package www.my.imageframecompare.multiImgContinue;

import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import org.apache.log4j.Logger;

/**
 * Created by Zen on 2017/8/11.
 */

public abstract class MyTimer {
    private Logger logger = Logger.getLogger(MyTimer.class);
    /**
     * Millis since epoch when alarm should stop.  eg: duration
     */
    private long mMillisInFuture;

    /**
     * The interval in millis that the user receives callbacks
     */
    private long mInterval;

    private long mStopTimeInFuture;
    private int index;

    private boolean isCountdown=false;//todo 暂时没有理解含义

    private long mPauseTime=0;

    /**
     * boolean representing if the timer was cancelled
     */
    private boolean mCancelled = false;


    /**
     * @param millisInFuture The number of millis in the future from the call
     *   to {@link #start()} until the countdown is done and {@link #onFinish()}
     *   is called.
     * @param interval The interval along the way to receive
     *   {@link #onTick(long)} callbacks.
     */
    public MyTimer(long millisInFuture, long interval) {
        logger.info(" MyTimer   millisInFuture=="+millisInFuture+"   interval=="+interval);
        mMillisInFuture = millisInFuture;
        mInterval = interval;
    }

    public MyTimer() {

    }

    public synchronized final void init(long millisInFuture, long interval ,int index){
        mHandler.removeMessages(MSG_RUN);
        mHandler.removeMessages(MSG_PAUSE);
        logger.info(" MyTimer init() millisInFuture=="+millisInFuture+"  interval"+interval);
        mMillisInFuture = millisInFuture;
        // TODO: 2018/7/6 修改所有延时为200 ms 因为后台最小刻度为1 秒，如果设置延时1秒 将导致1秒的节目无法播放
        mInterval = interval;
        mPauseTime = 0;
        this.index = index;
    }

    /**
     * Cancel the countdown.
     */
    public synchronized final void cancel() {
        mCancelled = true;
        mHandler.removeMessages(MSG_RUN);
        mHandler.removeMessages(MSG_PAUSE);
    }

    public synchronized final void pause(){
        mHandler.removeMessages(MSG_RUN);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_PAUSE));
    }
    public synchronized final void resume(){
        mHandler.removeMessages(MSG_PAUSE);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_RUN));
    }

    public synchronized final void setCountdown(boolean isCountdown){
        this.isCountdown=isCountdown;
    }

    /**
     * Start the countdown.
     */
    public synchronized final MyTimer start() {
        logger.info(" start()");
        mCancelled = false;
        if (mMillisInFuture <= 0) {
            onFinish(index);
            return this;
        }
        mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
        logger.info(" start()  SystemClock.elapsedRealtime()=="+SystemClock.elapsedRealtime()+"  mMillisInFuture=="+mMillisInFuture
                        +"  mStopTimeInFuture=="+mStopTimeInFuture);

        mHandler.sendMessage(mHandler.obtainMessage(MSG_RUN));
        return this;
    }




    /**
     * Callback fired on regular interval.
     * 非精确
     * @param millis The amount of time until finished.
     */
    public void onTick(long millis){

    }

    /**
     * Callback fired when the time is up.
     */
    public abstract void onFinish(int currentIndex);


    private static final int MSG_RUN = 1;
    private static final int MSG_PAUSE = 2;

    private static final String TAG = "MyTimer";
    // handles counting down
    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            synchronized (MyTimer.this) {
//                Log.i(TAG, ">>>>>>>>handleMessage: msg.what==RUN=="+(msg.what==MSG_RUN)+"    MSG_PAUSE=="+(msg.what==MSG_PAUSE)
//                        +"  mStopTimeInFuture=="+mStopTimeInFuture +"  mPauseTime== "+mPauseTime +"  mCancelled=="+mCancelled +"  isCountdown== "+isCountdown+"  mInterval=="+mInterval);
                if (mCancelled) {
                    return;
                }
                if(msg.what==MSG_RUN){
                    if (mPauseTime!=0) {
                        mStopTimeInFuture=mStopTimeInFuture+SystemClock.elapsedRealtime()-mPauseTime;
                        Log.i(TAG, "handleMessage: mPauseTime!=0 mStopTimeInFuture=="+mStopTimeInFuture);
                        mPauseTime=0;
                    }
                    final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();

                    if (millisLeft <= 0) {
                        mCancelled=true;
                        onFinish(index);
                    } else if (millisLeft < mInterval) {
                        // no tick, just delay until done
                        sendMessageDelayed(obtainMessage(MSG_RUN), millisLeft);
                    } else {
                        long lastTickStart = SystemClock.elapsedRealtime();

                        //************************************** start 暂时没有搞懂设计者的意图 ？isCountdown ？
                        long millis;
                        if(isCountdown){
                            millis=millisLeft; //已经执行了的时间
                        }else{
                            millis=mMillisInFuture-millisLeft; //已经执行了后，剩余未播放的时间
                        }
                        //***************************************  end
                        onTick(millis);

                        // take into account user's onTick taking time to execute
                        long delay = lastTickStart + mInterval - SystemClock.elapsedRealtime();

                        // special case: user's onTick took more than interval to
                        // complete, skip to next interval
                        while (delay < 0) {
                            delay += mInterval;
                        }

                        sendMessageDelayed(obtainMessage(MSG_RUN), delay);
                    }
                }else if(msg.what==MSG_PAUSE){
                    logger.info("MSG_PAUSE=="+mPauseTime +"  elapsedRealtime" +SystemClock.elapsedRealtime());
                    if (mPauseTime==0) {//2018-12-10 18:48:40   标志着从第一次pause的时间点开始播放。
                        mPauseTime=SystemClock.elapsedRealtime();
                    }
                }

            }
        }
    };
}
